using System;
using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.Media;
using GameEngine.options;
using Imaginarium.Factorys;
using Imaginarium.team;
using GameEngine.Scenes;
using Imaginarium.Scenes;

namespace Imaginarium
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class ImaginariumGame : Microsoft.Xna.Framework.Game
    {
        #region SingletonPattern
        //Singleton Pattern
        private static ImaginariumGame instance;
        public static ImaginariumGame getInstance()
        {
            if (instance == null)
            {
                instance = new ImaginariumGame();
            }
            return instance;
        }
        #endregion

        // Resources for drawing.
        private GraphicsDeviceManager graphics;
        private SpriteBatch spriteBatch;

        
        // When the time remaining is less than the warning time, it blinks on the hud
        private static readonly TimeSpan WarningTime = TimeSpan.FromSeconds(30);

        private const int TargetFrameRate = 60;
        private const int BackBufferWidth = 1280;
        private const int BackBufferHeight = 720;

        private ImaginariumGame()
        {
            graphics = new GraphicsDeviceManager(this);
            //Setting GraphicOptions
            GraphicOptions.getInstance().graphics = graphics;
            GraphicOptions.getInstance().screenResolution = new Vector2(BackBufferWidth, BackBufferHeight);
            graphics.PreferredBackBufferWidth = BackBufferWidth;
            graphics.PreferredBackBufferHeight = BackBufferHeight;
            Content.RootDirectory = "Content";

            // Framerate differs between platforms.
            TargetElapsedTime = TimeSpan.FromTicks(TimeSpan.TicksPerSecond / TargetFrameRate);
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            GraphicOptions.getInstance().auxTarget = new RenderTarget2D(graphics.GraphicsDevice,
                (int)GraphicOptions.getInstance().screenResolution.X, (int)GraphicOptions.getInstance().screenResolution.Y,
                1, SurfaceFormat.Color);

            SceneManager sm = SceneManager.getInstance();
            BattleScene battleS = new BattleScene();
            sm.scenes.Add(battleS); //despues cambiar para menu principal
            battleS.LoadContent();

            /*ActorFactory af = new ActorFactory();
            Enemy enemy = af.getEnemyById(51);
            Console.WriteLine(enemy.ToString());*/
            /* Music Stuff
            MediaPlayer.IsRepeating = true;
            MediaPlayer.Play(Content.Load<Song>("Sounds/Music"));
            */
            //LoadNextLevel();
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            SceneManager.getInstance().update(gameTime);

            base.Update(gameTime);
        }

        private void HandleInput()
        {
            KeyboardState keyboardState = Keyboard.GetState();
            GamePadState gamepadState = GamePad.GetState(PlayerIndex.One);

        }

        private void LoadNextLevel()
        {
            //??
            //level = new Level(Services, levelPath);            
        }

        private void ReloadCurrentLevel()
        {
            LoadNextLevel();
        }

        /// <summary>
        /// Draws the game from background to foreground.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

            SceneManager.getInstance().draw(spriteBatch);
            //level.Draw(gameTime, spriteBatch);

            base.Draw(gameTime);
        }

/*        private void DrawHud()
        {
            Rectangle titleSafeArea = GraphicsDevice.Viewport.TitleSafeArea;
            Vector2 hudLocation = new Vector2(titleSafeArea.X, titleSafeArea.Y);
            Vector2 center = new Vector2(titleSafeArea.X + titleSafeArea.Width / 2.0f,
                                         titleSafeArea.Y + titleSafeArea.Height / 2.0f);

            // Draw time remaining. Uses modulo division to cause blinking when the
            // player is running out of time.
            string timestring = "TIME: " + level.TimeRemaining.Minutes.Tostring("00") + ":" + level.TimeRemaining.Seconds.Tostring("00");
            Color timeColor;
            if (level.TimeRemaining > WarningTime ||
                level.ReachedExit ||
                (int)level.TimeRemaining.TotalSeconds % 2 == 0)
            {
                timeColor = Color.Yellow;
            }
            else
            {
                timeColor = Color.Red;
            }
            DrawShadowedstring(hudFont, timestring, hudLocation, timeColor);

            // Draw score
            float timeHeight = hudFont.Measurestring(timestring).Y;
            DrawShadowedstring(hudFont, "SCORE: " + level.Score.Tostring(), hudLocation + new Vector2(0.0f, timeHeight * 1.2f), Color.Yellow);

            // Determine the status overlay message to show.
            Texture2D status = null;
            if (level.TimeRemaining == TimeSpan.Zero)
            {
                if (level.ReachedExit)
                {
                    status = winOverlay;
                }
                else
                {
                    status = loseOverlay;
                }
            }
            else if (!level.Player.IsAlive)
            {
                status = diedOverlay;
            }

            if (status != null)
            {
                // Draw status message.
                Vector2 statusSize = new Vector2(status.Width, status.Height);
                spriteBatch.Draw(status, center - statusSize / 2, Color.White);
            }
        }*/
    }
}
